/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2003-2011,  Jin Chen and Alan M. MacEachren, GeoVISTA Center, Penn State University
 * All Rights Researved.
 *
 * This library is developed and distributed for free usage,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * You can redistribute and/or modify it under the terms of the
 * Simplified BSD License
 *
 *
 *
 *
 *
 *
 *
 *
 * Store data IDs for some purpose (e.g. display)
 * @author: jin Chen
 * @date: Jul 24, 2003$
 * @version: 1.0
 */
package edu.psu.geovista.app.pcp.toolkits.group;

import edu.psu.geovista.group.IndexSet;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class DataIDSet implements IndexSet,Comparable{
    public static final String TYPE_DisplayData="dd";
    public static final String TYPE_AxisShowRangeData="sr";
    public static final String TYPE_CategoryData="cd";
    public static final String TYPE_SelectData="sd";

    Set IDs=new HashSet();
    //int[] ids;
    String type;//the purpose of the dataset. The value can be one the TYPE_XXX defined in the class
    //String name;  //the name of the Set.for display purpose only, not act as ID
    String id;//for identify the DataIDSet
    int index; //can be used for the index in DataIDGroup

    public DataIDSet() {
    }

    public DataIDSet(int[] ids) {
        IDs=convertArrayToSet(ids);
        //this.ids = ids;

    }
    public DataIDSet(Set idset) {
        IDs=idset;
        //this.ids= DataGroup.convertToIntArray(idset);
    }

    public DataIDSet(Set idset, String type) {
        IDs=idset;
        //this.ids= DataGroup.convertToIntArray(idset);
        this.type = type;
    }
    public DataIDSet(int[] ids, String type) {
        IDs=convertArrayToSet(ids);
        //this.ids = ids;
        this.type = type;
    }

    public void add(int id) {
        IDs.add(new Integer(id));
    }
     public void remove(int id) {
        IDs.remove(new Integer(id));
    }
    /**
     *
     * @return
     */
    public Set getIdAsSet(){
        return (HashSet)convertArrayToSet(this.getIndice() );
    }
    //not implement yet
    public float[] getValues() {
        return new float[0];  //To change body of implemented methods use File | Settings | File Templates.
    }
    //not implement yet
    public void setValues(float[] v) {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public int[] getIndice() {
        return convertToIntArray(IDs);        //return ids;;
    }

    public void setIndice(int[] ids) {
        IDs=convertArrayToSet(ids);
        //this.ids = ids;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
    public int size(){
        return IDs.size();
    }


    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }
    public int compareTo(Object o) {
        DataIDSet another=(DataIDSet)o;
        if (this.getIndex() <another.getIndex() ){
            return -1;
        }
        else if  (this.getIndex() >another.getIndex() ){
            return 1;
        }
        else{
                return 0;
        }
    }

    /**
        *
        * @param a
        * @param b
        * @return  join Union of two dataGroup. If one =null(e.g. Not set yet), it won't affect anything. Only return the other's ID.
        */
       public static int[] joinUnionDataIDSet(DataIDSet a, DataIDSet b){
           int[] result=null;
           if(isDataGroupValid(a)&&isDataGroupValid(b)){
               int[] aData=a.getIndice() ;
               int[] bData=b.getIndice() ;
               result= DataIDSet.getJoinUnion(aData,bData);
           }
           else if (isDataGroupValid(a)&&!isDataGroupValid(b)){
               result=a.getIndice() ;
           }
           else if (!isDataGroupValid(a)&&isDataGroupValid(b)){
                result=b.getIndice() ;
           }
           else{
               result=null;
           }
           return result;

       }

    /**
     *
     * @param a      an int array
     * @param b      an int array
     * @return       an array contain join union of given 2 arrays
     */
    public static int[] getJoinUnion(int[] a,int[] b) {
        if(a==null ||b==null){
            throw new NullPointerException("Not allow null array");
        }
         int[] searchedArray;
         int[] keyArray;
        HashSet junion=new HashSet();
        int[] jn;
        Arrays.sort(a);
        Arrays.sort(b);
        if(a.length >b.length ){
             searchedArray=a;
             keyArray=b;
        }
        else{
            searchedArray=b;
             keyArray=a;
        }
        for (int i=0;i<keyArray.length ;i++){
            int key=keyArray[i];
            int index=Arrays.binarySearch(searchedArray,key);
            if(index>=0){//found
                junion.add(new Integer(key));
            }

        }
        jn=convertToIntArray(junion);

        return jn;

    }
    /**
     *
     * @param dg
     * @return false is dg is null or dg'getIds() return null
     */
    public static boolean isDataGroupValid(DataIDSet dg ) {
       if(dg==null||dg.getIndice() ==null){
           return false;
       }
       return true;
    }

    public static int[] convertToIntArray(Set set){
        int[] intA;
        if (set.size() <=0){
            intA=null;
        }
        else{
           intA=new int[set.size() ];
            Object[] tmp=set.toArray() ;
            for (int i=0;i<intA.length ;i++){
                intA[i]=((Integer)tmp[i]).intValue() ;
            }
        }
          return intA;
    }

    public static Set convertArrayToSet(int[] array){
        HashSet set=new HashSet();
        if (array==null)return set;        
        for (int i=0;i<array.length ;i++){
            Integer e=new Integer(array[i]);
            set.add(e);
        }
        return set;
    }

}
